﻿using System;
using System.Configuration;
using Cms.Utilities.DatabaseUpdaters;
using iLib.DataAccess;

namespace Cms.Utilities
{
    internal abstract class DatabaseUpdater
    {
        #region Delegates

        public delegate void PatchDelegate();

        #endregion

        protected IDataAccessManager Dam { get; set; }
        
        public static DatabaseUpdater Create()
        {
            string connectionString = ConfigurationManager.ConnectionStrings["Fredium"].ConnectionString;
            switch (ConfigurationManager.AppSettings["DatabaseType"])
            {
                case "SqlServer2008":
                case "SqlServer2005":
                case "SqlServer2000":
                    return new SqlServer2005Updater(connectionString);
                case "Access":
                    return new AccessUpdater(connectionString);
            }
            throw new Exception("DatabaseType not recognized.");
        }

        public abstract void Patch_0_9_12325_471();
        public abstract void Patch_0_9_12310_469();
        public abstract void Patch_0_9_12309_468();
        public abstract void Patch_0_9_12309_464();
        public abstract void Patch_0_9_12303_463();
        public abstract void Patch_0_9_12297_462();
        public abstract void Patch_0_9_12256_457();
        public abstract void Patch_0_9_12216_454();
        public abstract void Patch_0_9_12165_446();
        public abstract void Patch_0_9_12141_437();
        public abstract void Patch_0_9_12114_419();
        public abstract void Patch_0_9_12078_398();
        public abstract void Patch_0_9_12073_394();
        public abstract void Patch_0_9_12052_387();
        public abstract void Patch_0_9_12026_376();
        public abstract void Patch_0_9_12021_372();
        public abstract void Patch_0_9_12016_369();
        public abstract void Patch_0_9_11229_341();
        public abstract void Patch_0_9_11227_337();
        public abstract void Patch_0_9_11170_327();
        public abstract void Patch_0_9_11163_317();
        public abstract void Patch_0_9_11139_313();
        public abstract void Patch_0_9_11137_306();
        public abstract void Patch_0_9_11133_300();
        public abstract void Patch_0_9_11095_265();
        public abstract void Patch_0_9_11095_264();
        public abstract void Patch_0_9_11095_262();
        public abstract void Patch_0_9_11064_247();
        public abstract void Patch_0_9_10243_211();
        public abstract void Patch_0_9_10237_191();
        public abstract void Patch_0_9_10237_184();
        public abstract void Patch_0_9_10232_183();
        public abstract void Patch_0_9_10232_182();
        public abstract void Patch_0_9_10229_157();
        public abstract void Patch_0_8_10228_130();
        public abstract void Patch_0_8_10182_123();
        public abstract void Patch_0_7_10180_115();
        public abstract void Patch_0_7_10175_107();
        public abstract void Patch_0_7_10175_105();
        public abstract void Patch_0_7_10175_104();
        public abstract void Patch_0_7_10175_103();
        public abstract void Patch_0_7_10173_95();
        public abstract void Patch_0_7_10172_94();
        public abstract void Patch_0_7_10172_93();

        public void ApplyPatch(string version, PatchDelegate patch)
        {
            try
            {
                Dam.OpenConnection();
                Dam.BeginTransaction(true);
                patch();
                Dam.CommitTransaction();
                Logging.LogInfo("Patch " + version + " applied");
            }
            catch (Exception ex)
            {
                Dam.RollbackTransaction();
                Logging.LogError("Database Patch " + version + " failed.", ex);
            }
            finally
            {
                Dam.CloseConnection();
            }
        }
    }
}